package com.ctshk.rpc.order.localfun.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.constant.CurrencyIdCode;
import com.ctshk.common.constant.CurrencyRateExchangeConstant;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.common.constant.SystemConstants;
import com.ctshk.common.dto.Result;
import com.ctshk.common.dto.payment.CallPayDTO;
import com.ctshk.common.enums.*;
import com.ctshk.common.enums.appUser.AppOrderStatus;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.req.pay.NotifyConsumeReq;
import com.ctshk.common.utils.CalcIntegralUtil;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.booking.enums.SupplierReserveTypeEnum;
import com.ctshk.rpc.booking.req.system.localfun.add.SupplierOrderSystemLocalFunAddReq;
import com.ctshk.rpc.booking.req.system.localfun.add.SupplierSystemOrderLocalFunAddReq;
import com.ctshk.rpc.booking.req.system.localfun.add.SupplierSystemOrderLocalFunDetailAddReq;
import com.ctshk.rpc.booking.service.ISupplierOrderService;
import com.ctshk.rpc.finance.json.AccountJson;
import com.ctshk.rpc.finance.req.bill.BillAddCollectionReq;
import com.ctshk.rpc.finance.req.bill.BillAddRefundReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.finance.service.IFinanceOnAccountCurrencyQuotaService;
import com.ctshk.rpc.finance.service.IFinanceOnAccountService;
import com.ctshk.rpc.localfun.dto.*;
import com.ctshk.rpc.localfun.dto.es.PhotosJson;
import com.ctshk.rpc.localfun.req.LocalFunPriceReq;
import com.ctshk.rpc.localfun.req.LocalFunProductDetailReq;
import com.ctshk.rpc.localfun.req.LocalFunProductOrderReq;
import com.ctshk.rpc.localfun.req.LocalFunStockReq;
import com.ctshk.rpc.localfun.service.*;
import com.ctshk.rpc.order.localfun.LocalFunOrderPay;
import com.ctshk.rpc.order.localfun.dto.*;
import com.ctshk.rpc.order.localfun.entity.*;
import com.ctshk.rpc.order.localfun.generator.LocalFunOrderGenerator;
import com.ctshk.rpc.order.localfun.mapper.*;
import com.ctshk.rpc.order.localfun.req.*;
import com.ctshk.rpc.order.localfun.req.h5.LocalFunH5OrderPorductReq;
import com.ctshk.rpc.order.localfun.req.h5.LocalFunH5OrderReq;
import com.ctshk.rpc.order.localfun.req.h5.LocalFunH5OrderTourisReq;
import com.ctshk.rpc.order.localfun.req.h5.LocalFunOrderAppCallPayReq;
import com.ctshk.rpc.order.localfun.schedule.OrderCancelScheduleTask;
import com.ctshk.rpc.order.localfun.service.ILocalFunAppOrderService;
import com.ctshk.rpc.order.localfun.service.ILocalFunOrderReceiptService;
import com.ctshk.rpc.order.season.service.ISeasonOrderService;
import com.ctshk.rpc.payment.enums.PayCurrency;
import com.ctshk.rpc.payment.enums.PaymentMethod;
import com.ctshk.rpc.payment.req.PayCommonReq;
import com.ctshk.rpc.payment.service.IPayService;
import com.ctshk.rpc.starvip.req.TransactionIntegralReq;
import com.ctshk.rpc.starvip.service.IStarVipBusinessService;
import com.ctshk.rpc.system.dto.MainDataCurrencyQueryDTO;
import com.ctshk.rpc.system.dto.SysDepartmentDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.req.DispatchOrderRuleGetUserReq;
import com.ctshk.rpc.system.service.*;
import com.ctshk.rpc.user.dto.AppUserDTO;
import com.ctshk.rpc.user.service.IOrderEsService;
import com.ctshk.rpc.user.service.IUserService;
import com.ctshk.rpc.user.service.IUserSmsService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import com.github.houbb.heaven.util.lang.StringUtil;
import com.github.kfcfans.powerjob.client.OhMyClient;
import com.github.kfcfans.powerjob.common.response.ResultDTO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

//import com.ctshk.common.utils.MailUtil;

/**
 * @Description
 * @Author wansi <gaylen15527491065@yeah.net>
 * @Date 2021/3/29
 */
@Slf4j
@DubboService
public class LocalFunAppOrderServiceImpl extends ServiceImpl<LocalFunOrderMapper, LocalFunOrder> implements ILocalFunAppOrderService {

    @Autowired
    private LocalFunOrderMapper localFunOrderMapper;
    @Autowired
    private LocalFunOrderTouristMapper localFunOrderTouristMapper;

    @Autowired
    private LocalFunManualOrderMapper localFunManualOrderMapper;

    @Autowired
    private LocalFunOrderCollectionMapper localFunOrderCollectionMapper;

    @Autowired
    private LocalFunOrderRefundMapper localFunOrderRefundMapper;

    @Autowired
    LocalFunOrderReceiptMapper scenicOrderReceiptMapper;

    @DubboReference
    private ILocalFunProductService iLocalFunProductService;

    @DubboReference
    private IMainDataCurrencyService iMainDataCurrencyService;

    @DubboReference
    private ISysPermissionService sysPermissionService;

    @DubboReference
    private ILocalFunProductCostStrategySpecAttrService localFunProductCostStrategySpecAttrService;

    @DubboReference
    private ISysUserService iSysUserService;

    @DubboReference
    private IUserService userService;

    @DubboReference
    private ISysDepartmentService iSysDepartmentService;

    @DubboReference
    private ILocalFunOrderReceiptService iLocalFunOrderReceiptService;

    @DubboReference
    private ISupplierOrderService iSupplierOrderService;

    @DubboReference
    private ILocalFunResourceService iLocalFunResourceService;

    @DubboReference
    private ILocalFunProductSaleRecordService localFunProductSaleRecordService;

    @DubboReference
    private ISysApprovalService iSysApprovalService;

    @DubboReference
    private IFinanceBillService iFinanceBillService;

    @DubboReference
    private ISeasonOrderService iSeasonOrderService;

    @DubboReference
    private ILocalFunCostPriceService costPriceService;

    @DubboReference
    private IFinanceOnAccountService iFinanceOnAccountService;

    @DubboReference
    private IFinanceOnAccountCurrencyQuotaService onAccountCurrencyQuotaService;

    @Autowired
    LocalFunOrderReceiptMapper localFunOrderReceiptMapper;

    @DubboReference
    ILocalFunAppProductService iLocalFunAppProductService;

    @DubboReference
    private IOrderEsService orderEsService;

    @Value("${schedule.config.domain}")
    private String domain;

    @Value("${schedule.config.app-name}")
    private String appName;

    @Value("${schedule.config.password}")
    private String password;

    @Value("${schedule.job-id.order.localfun}")
    private long jobId;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @DubboReference
    private IStarVipBusinessService iStarVipBusinessService;
    @DubboReference
    private IDispatchOrderRuleService iDispatchOrderRuleService;
    @DubboReference
    private IPayService payService;

    @DubboReference
    private ILocalFunAppProductService  appProductService;

    @DubboReference
    private IUserSmsService userSmsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> submit(LocalFunH5OrderReq localFunAppOrderReq, Long loginUserId) {
        //校验余票
        if(appProductService.noMoreSurplusNumber(localFunAppOrderReq.getLocalFunAppOrderPorductReq().getProductId(),localFunAppOrderReq.getLocalFunAppOrderPorductReq().getAttr1Id(),
                localFunAppOrderReq.getLocalFunAppOrderPorductReq().getAttr2Id(),3,localFunAppOrderReq.getLocalFunAppOrderPorductReq().getChannelId())){

            return Result.failed(SystemError.LOCAL_FUN_18016);
        }
        UserDTO userDTO = getUserDTO(localFunAppOrderReq.getCompanyType());
        //生成订单ID
        long orderId = SnowflakeIdWorker.nextId();
        //1.保存订单信息
        saveOrderInfo(localFunAppOrderReq.getLocalFunAppOrderPorductReq(),userDTO, orderId, 1,userDTO.getId(),localFunAppOrderReq.getOrderSource(),loginUserId);
        //2.登记旅客资料
        registerTouristInfo(userDTO.getId(),orderId,localFunAppOrderReq);
        //3.保存取票信息
        sendOrderToAppUser(orderId);
        //4.减产品库存
        reduceRepository(localFunAppOrderReq, userDTO, orderId);
        return Result.success(orderId);
    }

    /**
     * 减产品库存
     * @param localFunAppOrderReq
     * @param userDTO
     * @param orderId
     */
    protected void reduceRepository(LocalFunH5OrderReq localFunAppOrderReq, UserDTO userDTO, long orderId) {
        try {
            String productTicketsIds = localFunAppOrderReq.getLocalFunAppOrderPorductReq().getAttr1Id()+","+localFunAppOrderReq.getLocalFunAppOrderPorductReq().getAttr2Id();
            if(StringUtil.isNotEmpty(productTicketsIds)){
                String[] attrIds = productTicketsIds.split(",");
                Long attrId1 = Long.valueOf(attrIds[0]);
                Long attrId2 = null;
                if(attrIds.length > 1) attrId2 = Long.valueOf(attrIds[1]);
                localFunProductSaleRecordService.operateStock(LocalFunStockReq.builder().attrId1(attrId1)
                        .attrId2(attrId2)
                        .num(localFunAppOrderReq.getLocalFunAppOrderPorductReq().getNum())
                        .userId(userDTO.getId()).productId(localFunAppOrderReq.getLocalFunAppOrderPorductReq().getProductId()).orderId(orderId)
                        //线上
                        .line(1)
                        .channel(3)
                        .customId(ChannelMainData.APP_H5.getId()).customName(ChannelMainData.APP_H5.getMsg()).build());
            }
        } catch (NumberFormatException e) {
            log.error("减库存失败：{}",e.getMessage());
        }
    }


    /**
     * 根据订单id查询订单信息
     *
     * @param orderId 订单id
     * @return 订单信息
     */
    @Override
    public Result<LocalFunOrderPayQueryInfoDTO> queryOrderInfo(Long orderId) {
        try {
            LocalFunOrder localFunOrder = localFunOrderMapper.selectById(orderId);
            if (null == localFunOrder) {
                throw new BusinessException(SystemError.SYS_411);
            }
            // 应收总额
            BigDecimal orderAmount = localFunOrder.getOrderAmount();
            LocalDateTime time = localFunOrder.getGmtCreate();
            LocalDateTime payDueTime = time.plusMinutes(30);
            LocalFunOrderPayQueryInfoDTO payOrderDTO = new LocalFunOrderPayQueryInfoDTO();
            payOrderDTO.setOrderAmount(orderAmount);
            payOrderDTO.setPayDueTime(payDueTime);
            return Result.success(payOrderDTO);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failed(new BusinessException(SystemError.SYS_500));
    }


    /**
     * 获取用户信息
     * @param companyType 公司类型
     * @return
     */
    private UserDTO getUserDTO(String companyType) {
        //获取用户信息
        DispatchOrderRuleGetUserReq dispatchOrderRuleGetUserReq = new DispatchOrderRuleGetUserReq();
        dispatchOrderRuleGetUserReq.setBusinessTypeId(SystemBusinessType.LOCAL_FUN.getCode());
        if(StringUtil.isNotEmpty(companyType)){
            dispatchOrderRuleGetUserReq.setCompanyType(companyType);
        }else {
            dispatchOrderRuleGetUserReq.setCompanyType(CompanyType.HK_CT.getCode());
        }
        Result<Long> result = iDispatchOrderRuleService.getDispatchUserId(dispatchOrderRuleGetUserReq);
        if (!result.isSuccess()) {
            log.error("【船票-订单】获取销售人失败:{},msg:{}", result.getCode(), result.getMsg());
            throw new BusinessException(SystemError.getDefined(result.getCode()));
        }
        UserDTO userDTO = iSysUserService.queryCacheUser(result.getData());

        if(userDTO == null){
            throw new BusinessException(SystemError.USER_1002);
        }
        return userDTO;
    }

    @Override
    public PageResponse<LocalFunOrderDTO> list(LocalFunOrderReq scenicOrderReq, TokenUser tokenUser) {
        return null;
    }

    @Override
    public Result<LocalFunOrderDetailDTO> localFunOrderDetail(LocalFunOrderDetailReq scenicOrderDetailReq) {
        return null;
    }

    @Override
    public Result localFunOrderCollection(LocalFunOrderCollectionDetailReq scenic0rderCollectionDetailReq, TokenUser user) {
        return null;
    }


    /**
     * 修改订单状态
     *
     * @param orderId
     * @param localFunOrder
     * @param userId
     * @return
     */
    private Result<LocalFunResourceDetailDTO> updateOrderStatus(Long orderId, LocalFunOrder localFunOrder, Long userId) {
        UpdateWrapper<LocalFunOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(LocalFunOrder::getId, orderId);
        updateWrapper.lambda().set(LocalFunOrder::getModifiedId, userId);
        updateWrapper.lambda().set(LocalFunOrder::getGmtModified, LocalDateTime.now());
        updateWrapper.lambda().set(LocalFunOrder::getPaymentStatus, OrderPaymentStatus.ALREADY_PAYMENT.getCode());
        Result<LocalFunResourceDetailDTO> dtoResult = iLocalFunResourceService.productDetail(localFunOrder.getProductId());
        if (dtoResult.getData() != null) {
            LocalFunResourceDetailDTO entity = dtoResult.getData();
            // 下单后，立即确认，当前自行确认成功 ，二次确认：其他地方手动确认
            //立即确认
            if (entity.getBookConfirm() == 1) {
                updateWrapper.lambda().set(LocalFunOrder::getScheduledStatus, OrderScheduledStatus.RESERVE_SUCCESS.getCode());
                updateWrapper.lambda().set(LocalFunOrder::getGmtModified, LocalDateTime.now());
            }else {
                updateWrapper.lambda().set(LocalFunOrder::getScheduledStatus, OrderScheduledStatus.CONFIRM_RESERVE.getCode());
            }
        }
        baseMapper.update(null, updateWrapper);
        return dtoResult;
    }

    /**
     * 获取收款认款申请请求参数
     *
     * @param localFunOrder
     * @param localFunOrderCollection
     * @param dtoResult
     * @param tokenUser
     * @return
     */
    private List<BillAddCollectionReq> obtainCollectionApply(LocalFunOrder localFunOrder, LocalFunOrderCollection localFunOrderCollection, Result<LocalFunResourceDetailDTO> dtoResult, UserDTO tokenUser) {
        List<BillAddCollectionReq> list = Lists.newArrayListWithExpectedSize(10);
        BillAddCollectionReq req = new BillAddCollectionReq();
        req.setSaleOrderId(localFunOrder.getId());
        //单号
        req.setBillNumber(localFunOrderCollection.getCollectionNumber());
        req.setSaleOrderNumber(localFunOrder.getOrderNumber());
        //业务类型
        req.setBusinessType(SystemBusinessType.LOCAL_FUN.getCode());
        req.setCollectionAmount(localFunOrderCollection.getCollectionAmount());
        req.setCollectionTime(LocalDateTime.now());
        req.setCollectionTypeId(CollectionTypeIdCode.FULL.getCode());
        req.setCollectionTypeName(CollectionTypeIdCode.FULL.getMsg());
        req.setProductId(Lists.newArrayList(localFunOrder.getProductId()));
        req.setCollectionWayId(localFunOrderCollection.getCollectionWayId());
        req.setCollectionWayName(localFunOrderCollection.getCollectionWay());

        //产品名称、产品编号
        if (dtoResult.getData() != null) {
            LocalFunResourceDetailDTO en = dtoResult.getData();
            req.setProductName(en.getName());
            req.setProductNumber(en.getProductCode());
        }
        req.setSaleUserId(tokenUser.getId());
        req.setSaleUserName(tokenUser.getFullName());
        //销售部门
        SysDepartmentDTO sysDepartmentDTO = iSysDepartmentService.queryByUserId(tokenUser.getId());
        if (sysDepartmentDTO != null) {
            req.setSaleDeptId(sysDepartmentDTO.getId());
        }
        list.add(req);
        return list;
    }

    /**
     * 收款记录
     *
     * @param reqList
     * @param user
     * @param collectionReq
     * @param collectionNumber
     */
    private void createOrderCollection(List<LocalFunPayOrderCollectionReq> reqList, TokenUser user, LocalFunPayOrderCollectionReq collectionReq, String collectionNumber) {
        for (LocalFunPayOrderCollectionReq orderCollectionReq : reqList) {
            LocalFunOrderCollection localFunOrderCollection = EntityUtil.copy(orderCollectionReq, LocalFunOrderCollection.class);
            localFunOrderCollection.setId(SnowflakeIdWorker.nextId());
            localFunOrderCollection.setOrderId(collectionReq.getOrderId());
            localFunOrderCollection.setCollectionNumber(collectionNumber);
            localFunOrderCollection.setCreateId(user.getId());
            localFunOrderCollection.setGmtCreate(LocalDateTime.now());
            localFunOrderCollection.setGmtModified(LocalDateTime.now());
            localFunOrderCollection.setSalerId(user.getId());
            localFunOrderCollection.setSalerName(user.getUsername());
            String collectionCertificate = orderCollectionReq.getCollectionCertificateJson();
            if (StringUtils.isNotEmpty(collectionCertificate)) {
                String collectionCertificateJson = JSON.toJSONString(collectionCertificate);
                localFunOrderCollection.setCollectionCertificateJson(collectionCertificateJson);
            }
            localFunOrderCollectionMapper.insert(localFunOrderCollection);
        }
    }

    /**
     * 下订单之前的校验
     *
     * @param reqList
     * @param collectionReq
     * @return
     */
    private Result checkOrderBeforePay(List<LocalFunPayOrderCollectionReq> reqList, LocalFunPayOrderCollectionReq collectionReq) {
        if (CollectionUtils.isEmpty(reqList)) {
            throw new BusinessException(SystemError.SYS_416);
        }

        LocalFunOrder localFunOrder = baseMapper.selectById(collectionReq.getOrderId());
        //订单金额
        BigDecimal orderAmount = localFunOrder.getOrderAmount();
        //支付金额
        BigDecimal orderPayAmount = new BigDecimal(0);
        for (LocalFunPayOrderCollectionReq airOrderCollectionDetailReq : reqList) {
            if (airOrderCollectionDetailReq.getCurrencyId() != null) {
                BigDecimal crmExchangeRateByName = getCrmExchangeRateByName(String.valueOf(airOrderCollectionDetailReq.getCurrencyId()));
                orderPayAmount = orderPayAmount.add(airOrderCollectionDetailReq.getCollectionAmount().multiply(crmExchangeRateByName));
            } else {
                orderPayAmount = orderPayAmount.add(airOrderCollectionDetailReq.getCollectionAmount());
            }
        }

        log.info("订单金额：" + orderAmount + "---收款金额：orderPayAmount");
        if (orderAmount.compareTo(orderPayAmount) != NumberConstant.ZERO.getValue().intValue()) {
            return Result.failed(SystemError.AIR_ORDER_15001);
        }

        if (collectionReq.getIsUnionpayDiscount().intValue() == NumberConstant.ONE.getValue().intValue() &&
                (null == collectionReq.getUnionpayDiscountId() || collectionReq.getUnionpayDiscountId().intValue() < NumberConstant.ONE.getValue().intValue())) {
            return Result.failed(SystemError.AIR_ORDER_15003);
        }
        return null;
    }


    @Override
    public Result<Long> cancelLocalFunOrder(LocalFun0rderCancelReq localFun0rderCancelReq, Long userId) {
        LocalFunOrder shipOrder = localFunOrderMapper.selectById(localFun0rderCancelReq.getOrderId());
        shipOrder.setPaymentStatus(OrderPaymentStatus.ALREADY_CANCEL.getCode());
        shipOrder.setScheduledStatus(null);
        shipOrder.setCancelStatus(null);
        shipOrder.setModifiedId(userId);
        shipOrder.setGmtModified(LocalDateTime.now());
        shipOrder.setCancelReason(localFun0rderCancelReq.getCancelReason());
        localFunOrderMapper.updateById(shipOrder);
        updateStatusToAppUser(shipOrder.getId());

        //3.还库存
        try {
            if(StringUtil.isNotEmpty(shipOrder.getProductTicketsId())) {
                String[] attrIds = shipOrder.getProductTicketsId().split(",");
                Long attrId1 = Long.valueOf(attrIds[0]);
                Long attrId2 = null;
                if (attrIds.length > 1) attrId2 = Long.valueOf(attrIds[1]);
                localFunProductSaleRecordService.backToStock(shipOrder.getId(),shipOrder.getProductId(),
                        attrId1,attrId2,shipOrder.getTicketNum(),userId);
            }
        } catch (NumberFormatException e) {
            log.error("C端H5-待支付取消订单-减库存失败:{}",e.getMessage());
        }
        return Result.success(shipOrder.getId());
    }

    @Transactional
    @Override
    public Result<Long> cancelLocalFunOrderRefund(AppLocalFunOrderRefundDetailReq localFun0rderRefundDetailReq, Long userId) {
        LocalFunOrder localFunOrder = localFunOrderMapper.selectById(localFun0rderRefundDetailReq.getOrderId());
        if (ApprovalStatus.REVIEWING.getCode().equals(localFunOrder.getCancelStatus()) ||
                ApprovalStatus.REVIEW_YES.getCode().equals(localFunOrder.getCancelStatus())) {
            return Result.failed(SystemError.LOCAL_FUN_18012);
        }
        Result<ApprovalStartDTO> result = iSysApprovalService.start(SystemBusinessType.LOCAL_FUN.getCode(),
                SysApprovalType.CANCEL_LOCALFUN.getCode(), Long.parseLong(localFun0rderRefundDetailReq.getOrderId()), userId, null, JSON.toJSONString(localFun0rderRefundDetailReq));

        if (result.isSuccess()) {
            //1.修改订单状态
            localFunOrder = EntityUtil.copy(localFun0rderRefundDetailReq, LocalFunOrder.class);
            localFunOrder.setCancelStatus(ApprovalStatus.REVIEWING.getCode());
            localFunOrder.setGmtModified(LocalDateTime.now());
            localFunOrder.setRefundDate(LocalDateTime.now());
            localFunOrder.setModifiedId(userId);
            localFunOrder.setCancelReason(localFun0rderRefundDetailReq.getCancelReason());
            localFunOrder.setId(Long.valueOf(localFun0rderRefundDetailReq.getOrderId()));
            localFunOrderMapper.updateById(localFunOrder);
            updateStatusToAppUser(localFunOrder.getId());

            //退款记录
            saveRefundRecord(localFunOrder,localFun0rderRefundDetailReq,userId);

            //3.还库存
            try {
                if(StringUtil.isNotEmpty(localFunOrder.getProductTicketsId())) {
                    String[] attrIds = localFunOrder.getProductTicketsId().split(",");
                    Long attrId1 = Long.valueOf(attrIds[0]);
                    Long attrId2 = null;
                    if (attrIds.length > 1) attrId2 = Long.valueOf(attrIds[1]);
                    localFunProductSaleRecordService.backToStock(localFunOrder.getId(),localFunOrder.getProductId(),
                            attrId1,attrId2,localFunOrder.getTicketNum(),userId);
                }
            } catch (NumberFormatException e) {
                log.error("C端H5-待支付取消订单-减库存失败:{}",e.getMessage());
            }
        } else {
            Result result1 = new Result();
            result1.setCode(result.getCode());
            result1.setMsg(result.getMsg());
            return result1;
        }
        return Result.success(Long.valueOf(localFun0rderRefundDetailReq.getOrderId()));
    }

    private void saveRefundRecord(LocalFunOrder localFunOrder, AppLocalFunOrderRefundDetailReq localFun0rderRefundDetailReq, Long userId) {
        LocalFunOrderRefund localFunOrderRefund = new LocalFunOrderRefund();
        localFunOrderRefund.setRefundNumber(LocalFunOrderGenerator.getRefundNumber());
        localFunOrderRefund.setId(SnowflakeIdWorker.nextId());
        LocalFunOrderCollection localFunOrderCollection = localFunOrderCollectionMapper.selectOne(Wrappers.<LocalFunOrderCollection>lambdaQuery().eq(LocalFunOrderCollection::getOrderId, Long.valueOf(localFun0rderRefundDetailReq.getOrderId())));
        if(localFunOrderCollection != null){
            localFunOrderRefund.setRefundWayId(localFunOrderCollection.getCollectionWayId());
            localFunOrderRefund.setRefundWay(localFunOrderCollection.getCollectionWay());
            localFunOrderRefund.setRefundAccount(localFunOrderCollection.getPayer());
        }
        localFunOrderRefund.setCreateId(userId);
        localFunOrderRefund.setOrderId(Long.valueOf(localFun0rderRefundDetailReq.getOrderId()));
        localFunOrderRefund.setCurrencyId(CurrencyIdCode.HKD.getCode());
        localFunOrderRefund.setCurrency(CurrencyIdCode.HKD.getMsg());
        //中途退改后的价格
        BigDecimal refundAmount = getRefundAmount(localFunOrder);
        localFunOrderRefund.setRefundAmount(refundAmount);
        localFunOrderRefundMapper.insert(localFunOrderRefund);
    }


    public BigDecimal getRefundAmount(LocalFunOrder localFunOrder) {
        Result<LocalFunResourceDetailDTO> result = iLocalFunResourceService.productDetail(localFunOrder.getProductId());
        if(result != null && result.getData() != null){
            if(result.getData().getCtsChargeType() == null){
                return localFunOrder.getReceivableAmount();
            }
            //数值
            if(result.getData().getCtsChargeType() == 1){
                return localFunOrder.getReceivableAmount().subtract(result.getData().getCtsCharge());
            }else if(result.getData().getCtsChargeType() == 2){
                //获取规格信息
                try {
                    String productTicketsId = localFunOrder.getProductTicketsId();
                    String[] split = productTicketsId.split(",");
                    Long attrId1 = null;
                    Long attrId2 = null;
                    if(split.length > 0){
                        attrId1 = Long.valueOf(split[0]);
                    }
                    if(split.length == 2 && !"null".equals(split[1])){
                        attrId2 = Long.valueOf(split[1]);
                    }
                    LocalFunStockInfo costTouristStockInfo = iLocalFunAppProductService.getCostTouristStockInfo(attrId1, attrId2);
                    if(costTouristStockInfo != null){
                        return localFunOrder.getReceivableAmount().subtract(costTouristStockInfo.getCostPrice().multiply(new BigDecimal(0.01)).multiply(result.getData().getCtsCharge()));
                    }
                } catch (NumberFormatException e) {
                    log.error("获取规格信息失败");
                }
            }
        }
        return localFunOrder.getReceivableAmount();
    }

    /**
     * 退款认款申请
     *
     * @param localFun0rderRefundDetailReq
     * @param localFunOrder
     * @param tokenUser
     * @param refundNumber
     */
    private void refundAmountApply(LocalFunOrderRefundDetailReq localFun0rderRefundDetailReq, LocalFunOrder localFunOrder, TokenUser tokenUser, String refundNumber) {
        List<LocalFunOrderRefundListReq> reqList = localFun0rderRefundDetailReq.getLocalFun0rderRefundListReqList();
        if (CollectionUtils.isNotEmpty(reqList)) {
            List<BillAddRefundReq> ars = reqList.stream().map(entity -> {
                BillAddRefundReq req = new BillAddRefundReq();
                req.setBillNumber(refundNumber);
                req.setBusinessType(99);
                req.setCollectionAmount(entity.getRefundAmountReq().getCollectionAmount());
                req.setCurrencyId(entity.getRefundAmountReq().getCurrencyId());
                req.setCurrencyName(entity.getRefundAmountReq().getCurrency());
                req.setSaleOrderNumber(localFunOrder.getOrderNumber());
                req.setProductId(Lists.newArrayList(localFunOrder.getProductId()));
                req.setSaleUserId(tokenUser.getId());
                req.setSaleUserName(tokenUser.getUsername());
                req.setRefundTime(LocalDateTime.now());
                req.setSaleOrderNumber(localFunOrder.getOrderNumber());
                req.setRefundTypeId(Objects.isNull(entity.getLocalFun0rderRefundWayReq().getValue()) ? 0L : Long.valueOf(entity.getLocalFun0rderRefundWayReq().getValue()));
                req.setRefundType(entity.getLocalFun0rderRefundWayReq().getLabel());
                AccountJson json = new AccountJson();
                json.setCardNumber(entity.getRefundAccount());
                req.setRefundAccountJson(json);
                //汇率
                BigDecimal exchangeRate = iMainDataCurrencyService.getExchangeRate(entity.getRefundAmountReq().getCurrency(), CurrencyRateExchangeConstant.MARKET_EXCHANGE_RATE_);
                req.setExchangeRate(exchangeRate.doubleValue());

                //销售部门
                SysDepartmentDTO sysDepartmentDTO = iSysDepartmentService.queryByUserId(tokenUser.getId());
                if (sysDepartmentDTO != null) {
                    req.setSaleDeptId(sysDepartmentDTO.getId());
                }

                return req;
            }).collect(Collectors.toList());


            iFinanceBillService.addRefund(ars);
        }
    }


    /**
     * 还库存
     *
     * @param localFunOrder
     * @param payOrderReq
     * @param tokenUser
     */
    private void reBackRepository(LocalFunOrder localFunOrder, LocalFunOrderRefundDetailReq payOrderReq, TokenUser tokenUser) {
        localFunProductSaleRecordService.backToStock(localFunOrder.getId(), localFunOrder.getProductId(),
                payOrderReq.getAttrId1(), payOrderReq.getAttrId2(), localFunOrder.getTicketNum(), tokenUser.getId());
    }

    /**
     * 记录退款记录
     *
     * @param localFun0rderRefundDetailReq
     * @param tokenUser
     * @param refundNumber
     */
    private void saveOrderRefundRecord(LocalFunOrderRefundDetailReq localFun0rderRefundDetailReq, TokenUser tokenUser, String refundNumber) {
        List<LocalFunOrderRefundListReq> localFun0rderRefundListReqList = localFun0rderRefundDetailReq.getLocalFun0rderRefundListReqList();
        if (CollectionUtils.isNotEmpty(localFun0rderRefundListReqList)) {
            for (LocalFunOrderRefundListReq visa0rderRefundListReq : localFun0rderRefundListReqList) {
                LocalFunOrderRefund localFunOrderRefund = new LocalFunOrderRefund();
                localFunOrderRefund = EntityUtil.copy(visa0rderRefundListReq, LocalFunOrderRefund.class);
                LocalFunOrderRefundWayReq localFun0rderRefundWayReq = visa0rderRefundListReq.getLocalFun0rderRefundWayReq();
                localFunOrderRefund.setRefundWayId(Long.parseLong(localFun0rderRefundWayReq.getValue()));
                localFunOrderRefund.setRefundWay(localFun0rderRefundWayReq.getLabel());
                localFunOrderRefund.setRefundNumber(refundNumber);
                localFunOrderRefund.setId(SnowflakeIdWorker.nextId());
                localFunOrderRefund.setCreateId(tokenUser.getId());
                localFunOrderRefund.setOrderId(Long.valueOf(localFun0rderRefundDetailReq.getOrderId()));
                RefundAmountReq refundAmountReq = visa0rderRefundListReq.getRefundAmountReq();
                localFunOrderRefund.setCurrencyId(refundAmountReq.getCurrencyId());
                localFunOrderRefund.setCurrency(refundAmountReq.getCurrency());
                localFunOrderRefund.setRefundAmount(refundAmountReq.getCollectionAmount());
                localFunOrderRefundMapper.insert(localFunOrderRefund);
            }
        }
    }

    @Override
    public Result<Long> confirmOrder(LocalFunProductOrderReq localFunProductOrderReq, TokenUser tokenUser) {
        LocalFunOrder localFunOrder = localFunOrderMapper.selectById(localFunProductOrderReq.getOrderId());
        localFunOrder.setFileJson(localFunProductOrderReq.getFileJson());
        localFunOrder.setScheduledStatus(OrderScheduledStatus.RESERVE_SUCCESS.getCode());
        localFunOrderMapper.updateById(localFunOrder);
        return Result.success(localFunOrder.getId());
    }

    @Override
    public Result notice(LocalFunOrderNoticeReq localFun0rderNoticeReq) {
//        MailUtil.sendSimpleTextMail("1204920594@qq.com","","333");
        return Result.success();
    }

    @Override
    public Result<Long> updateOrderPaymentStatus(Long orderId) {
        LocalFunOrder localFunOrder = localFunOrderMapper.selectById(orderId);
        if (localFunOrder == null) {
            return Result.failed(SystemError.LOCAL_FUN_18010);
        }
        if (OrderPaymentStatus.UN_PAYMENT.getCode().equals(localFunOrder.getPaymentStatus())) {
            localFunOrder.setPaymentStatus(OrderPaymentStatus.ALREADY_CANCEL.getCode());
            localFunOrderMapper.updateById(localFunOrder);
        }
        return Result.success(orderId);
    }

    @Override
    @Transactional
    public Result<Long> refundOperate(LocalFunOrderCheckReq localFunProductCheckReq, TokenUser currentUser) {
        Result<ApprovalCheckDTO> result = iSysApprovalService.check(localFunProductCheckReq.getApprovalId(),currentUser.getId(),localFunProductCheckReq.getApprovalStatus(),localFunProductCheckReq.getComments());
        if(result.isSuccess()){
            if(result.getData().getIsFinish()){
                LocalFunOrder localFunOrder = localFunOrderMapper.selectById(localFunProductCheckReq.getBusinessId());
                if(localFunOrder == null){
                    throw new BusinessException(SystemError.LOCAL_FUN_18010);
                }
                localFunOrder.setGmtModified(LocalDateTime.now());
                localFunOrder.setModifiedId(currentUser.getId());
                localFunOrder.setCancelStatus(localFunProductCheckReq.getApprovalStatus());
                localFunOrder.setPaymentStatus(OrderPaymentStatus.ALREADY_CANCEL.getCode());
                localFunOrderMapper.updateById(localFunOrder);

                String refundNumber= LocalFunOrderGenerator.getRefundNumber();

                if(localFunProductCheckReq.getApprovalStatus() == 4){
                    UpdateWrapper<LocalFunOrderRefund> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.lambda().eq(LocalFunOrderRefund::getOrderId, localFunOrder.getId());
                    updateWrapper.lambda().set(LocalFunOrderRefund::getStatus,localFunProductCheckReq.getApprovalStatus());
                    localFunOrderRefundMapper.update(null,updateWrapper);
                }
                if(localFunProductCheckReq.getApprovalStatus() == 3){
                    //校验实际退款金额不能大于 订单金额
                    List<LocalRefundDTO> reqList = localFunProductCheckReq.getOrderRefundApprovalRecordReqList();
                    if(CollectionUtils.isNotEmpty(reqList)){
                        BigDecimal sums = new BigDecimal(0);
                        List<BigDecimal> bigDecimals = reqList.stream().filter(en->en.getApprovalAmount() != null).flatMap(en ->
                                Stream.of(en.getApprovalAmount())).collect(Collectors.toList());

                        for(BigDecimal amount : bigDecimals){
                            sums = sums.add(amount);
                        }
                        if(sums.compareTo(localFunOrder.getOrderAmount()) > 0){
                            throw new BusinessException(SystemError.LOCAL_FUN_18014);
                        }
                        UpdateWrapper<LocalFunOrderRefund> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.lambda().eq(LocalFunOrderRefund::getOrderId, localFunOrder.getId());
                        updateWrapper.lambda().set(LocalFunOrderRefund::getRefundAmount,sums);
                        localFunOrderRefundMapper.update(null,updateWrapper);
                    }
                    //2.更新退款审批状态
//                    updateRefundStatus(localFunOrder,localFunProductCheckReq);
//                    //3.还库存
//                    reBackRepository(localFunOrder,localFunProductCheckReq,currentUser);
//
//                    //4.退款认款申请
//                    refundAmountApply(localFunProductCheckReq,localFunOrder,currentUser,refundNumber);
                }
            }
        }else {
            Result result1 = new Result();
            result1.setCode(result.getCode());
            result1.setMsg(result.getMsg());
            return result1;
        }
        return Result.success(localFunProductCheckReq.getApprovalId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result payOrder(NotifyConsumeReq payOrderReq, Long userId) {
        String orderNumber = payOrderReq.getOrderNumber();
        if(StringUtil.isEmpty(orderNumber)){
            throw new BusinessException(SystemError.LOCAL_FUN_18029);
        }
        LocalFunOrder localFunOrder = localFunOrderMapper.selectOne(Wrappers.<LocalFunOrder>lambdaQuery().eq(LocalFunOrder::getOrderNumber, orderNumber));
        // 支付的订单不存在
        if(null == localFunOrder) return Result.failed(SystemError.LOCAL_FUN_18010);

        // 订单支付状态不是未支付
        if (!localFunOrder.getPaymentStatus().equals(OrderPaymentStatus.UN_PAYMENT.getCode())) {
            return Result.failed(SystemError.LOCAL_FUN_18018);
        }

        // 支付金额与数据库不一致
        if (!localFunOrder.getOrderAmount().equals(payOrderReq.getAmount())) {
            return Result.failed(SystemError.LOCAL_FUN_18001);
        }
        UserDTO userDTO = iSysUserService.queryCacheUser(localFunOrder.getSalesmanId());

        //1.收款记录
        LocalFunOrderCollection localFunOrderCollection = addPcCollection(payOrderReq, localFunOrder.getId());

        //2.记录收款凭据
        addOrderReceipt(userDTO, localFunOrder.getId(), localFunOrder);

        //3.生成供应预订单
        Result<LocalFunResourceDetailDTO> result = iLocalFunResourceService.productDetail(localFunOrder.getProductId());
        callSupplierOrder(userDTO,localFunOrder,result);

        //6.修改订单状态，返回产品信息
        Result<LocalFunResourceDetailDTO> dtoResult = updateOrderStatus(localFunOrder.getId(), localFunOrder,userId);

        //8.认款申请
        iFinanceBillService.addCollection(obtainCollectionApply(localFunOrder,localFunOrderCollection,dtoResult,userDTO));

        //9.减产品库存
        String productTicketsIds = localFunOrder.getProductTicketsId();
        if(StringUtil.isNotEmpty(productTicketsIds)){
            String[] attrIds = productTicketsIds.split(",");
            Long attrId1 = Long.valueOf(attrIds[0]);
            Long attrId2 = null;
            if(attrIds.length > 1) attrId2 = Long.valueOf(attrIds[1]);
            Long channelId = OrderSource.PC_NET.getCode().equals(localFunOrder.getSource()) ? ChannelMainData.CHINA_TRAVEL.getId() : ChannelMainData.APP_H5.getId();
            String channelName = OrderSource.PC_NET.getCode().equals(localFunOrder.getSource()) ? ChannelMainData.CHINA_TRAVEL.getMsg() : ChannelMainData.APP_H5.getMsg();
            localFunProductSaleRecordService.operateStock(LocalFunStockReq.builder().attrId1(attrId1)
                    .attrId2(attrId2)
                    .num(localFunOrder.getTicketNum())
                    .userId(userDTO.getId()).productId(localFunOrder.getProductId()).orderId(localFunOrder.getId())
                    //线上
                    .line(1)
                    .channel(3)
                    .customId(channelId).customName(channelName).build());
        }
        return Result.success(localFunOrder.getId());
    }

    @Override
    public Result payment(NotifyConsumeReq notifyConsumeReq) throws Exception {
        String orderNumber = notifyConsumeReq.getOrderNumber();
        if(StringUtil.isEmpty(orderNumber)){
            throw new BusinessException(SystemError.LOCAL_FUN_18029);
        }
        LocalFunOrder localFunOrder = localFunOrderMapper.selectOne(Wrappers.<LocalFunOrder>lambdaQuery().eq(LocalFunOrder::getOrderNumber, orderNumber));
        // 支付的订单不存在
        if(null == localFunOrder) return Result.failed(SystemError.LOCAL_FUN_18010);

        // 订单支付状态不是未支付
        if (!localFunOrder.getPaymentStatus().equals(OrderPaymentStatus.UN_PAYMENT.getCode())) {
            return Result.failed(SystemError.LOCAL_FUN_18018);
        }

        UserDTO userDTO = iSysUserService.queryCacheUser(localFunOrder.getSalesmanId());

        //1.收款记录
        notifyConsumeReq.setAmount(localFunOrder.getReceivableAmount());
        LocalFunOrderCollection localFunOrderCollection = addPcCollection(notifyConsumeReq, localFunOrder.getId());

        //2.记录收款凭据
        addOrderReceipt(userDTO, localFunOrder.getId(), localFunOrder);

        //3.生成供应预订单
        Result<LocalFunResourceDetailDTO> result = iLocalFunResourceService.productDetail(localFunOrder.getProductId());
        callSupplierOrder(userDTO,localFunOrder,result);

        //6.修改订单状态，返回产品信息
        Result<LocalFunResourceDetailDTO> dtoResult = updateOrderStatus(localFunOrder.getId(), localFunOrder,localFunOrder.getCreateId());

        //8.认款申请
        iFinanceBillService.addCollection(obtainCollectionApply(localFunOrder,localFunOrderCollection,dtoResult,userDTO));

        //发送短信通知
        try {
            Map<String, String> smsParam = new HashMap<>();
            smsParam.put("orderid", localFunOrder.getOrderNumber());
            smsParam.put("code", localFunOrder.getQueryNumber());
            Result smsResult = userSmsService.sendOrderSms(SystemBusinessType.LOCAL_FUN.getCode(), localFunOrder.getContactMobileAreaCode(), localFunOrder.getContactMobile(), smsParam);
            if (smsResult == null || !smsResult.isSuccess()) {
                throw new BusinessException(SystemError.SYS_437);
            }
            log.info("【当地玩乐支付-支付回调】, 支付成功, 短信通知完成");
        } catch (BusinessException e) {
            log.error("短信发送失败");
        }

        //更新订单状态到个人中心
        updateStatusToAppUser(localFunOrder.getId());
        return Result.success(localFunOrder.getId());
    }

    @Override
    public Result<LocalFunOrderDetail> orderDetail(LocalFunOrderDetailReq localFunOrderDetailReq, Long currentUserAllowNotLogInUserId) {
        LocalFunOrder localFunOrder = localFunOrderMapper.selectById(localFunOrderDetailReq.getOrderId());
        if(localFunOrder == null){
            throw new BusinessException(SystemError.LOCAL_FUN_18010);
        }
        LocalFunOrderDetail detail = EntityUtil.copy(localFunOrder, LocalFunOrderDetail.class);
        detail.setOrderDate(localFunOrder.getGmtCreate());

        //订单状态
        Integer paymentStatus = Objects.isNull(localFunOrder.getPaymentStatus())?0:localFunOrder.getPaymentStatus();
        Integer scheduledStatus = Objects.isNull(localFunOrder.getScheduledStatus())?0:localFunOrder.getScheduledStatus();
        Integer cancelStatus = Objects.isNull(localFunOrder.getCancelStatus())?0:localFunOrder.getCancelStatus();
        detail.setOrderStatus(getOrderStatus(paymentStatus,scheduledStatus,cancelStatus));

        //获取规格信息
        try {
            String productTicketsId = localFunOrder.getProductTicketsId();
            String[] split = productTicketsId.split(",");
            Long attrId1 = null;
            Long attrId2 = null;
            if(split.length > 0){
                attrId1 = Long.valueOf(split[0]);
            }
            if(split.length == 2 && !"null".equals(split[1])){
                attrId2 = Long.valueOf(split[1]);
            }
            LocalFunStockInfo costTouristStockInfo = iLocalFunAppProductService.getCostTouristStockInfo(attrId1, attrId2);
            if(costTouristStockInfo != null){
                detail.setAttrId1(attrId1);
                detail.setAttrId2(attrId2);
                detail.setAttrName1(costTouristStockInfo.getAttrName1());
                detail.setAttrName2(costTouristStockInfo.getAttrName2());
            }
        } catch (NumberFormatException e) {
            log.error("获取规格信息失败");
        }

        //购买后有效期
        Result<LocalFunResourceDetailDTO> result = iLocalFunResourceService.productDetail(localFunOrder.getProductId());
        if(result != null) {
            LocalFunResourceDetailDTO data = result.getData();
            if (data != null) {
                detail.setValidDay(data.getVaildDay());
                detail.setValidType(data.getVaildType());
                detail.setValidDayBegin(data.getVaildDayBegin());
                detail.setValidDayEnd(data.getVaildDayEnd());
                detail.setCustomerNotice(data.getCustomerNotice());
                detail.setCancelPolicy(data.getCancelPolicy());
                if(data.getVaildType() == 1){
                    detail.setUseDay(data.getVaildDay().intValue());
                }else {
                    //有效天数
                    if(data.getVaildDayBegin() != null && data.getVaildDayEnd() != null){
                        int daysBetween = DateUtil.daysBetween(data.getVaildDayEnd(), data.getVaildDayBegin());
                        detail.setUseDay(daysBetween);
                    }else {
                        detail.setUseDay(0);
                    }
                }

                //封面图地址
                List<PhotosJson> photosJsons = Objects.isNull(data.getPhotosJson()) ? Lists.newArrayListWithCapacity(1) : JSON.parseArray(data.getPhotosJson(), PhotosJson.class);
                if(CollectionUtil.isNotEmpty(photosJsons)){
                    PhotosJson photosJson1 = photosJsons.get(0);
                    detail.setCoverImage(photosJson1 != null ? photosJson1.getUrl() : "");
                }
            }
        }

        //取消订单退款状态和时间
        detail.setIntegralStatus(1);
        if(cancelStatus ==ApprovalStatus.REVIEWING.getCode()){
            //提交审批
            detail.setRefundStatus(1);
            detail.setRefundDate(localFunOrder.getRefundDate());
        }else if(cancelStatus == ApprovalStatus.REVIEW_YES.getCode()){
            detail.setRefundStatus(2);
            detail.setIntegralStatus(2);
            detail.setRefundApproveDate(localFunOrder.getRefundApproveDate());
            //审批通过
        }else if(cancelStatus == ApprovalStatus.REFUND_SUCCESS.getCode()){
            //退款成功
            detail.setRefundStatus(3);
            detail.setRefundSuccessDate(localFunOrder.getRefundSuccessDate());
        }

        //完成订单可获取积分
        try {
            AppUserDTO userDTO = userService.queryCacheUser(currentUserAllowNotLogInUserId);
            int integral = CalcIntegralUtil.getObtainByType(SystemBusinessType.LOCAL_FUN.getCode(), userDTO.getMemberLevel(), localFunOrder.getReceivableAmount());
            detail.setIntegral(integral);
        } catch (Exception e) {
            detail.setIntegral(0);
            log.error("获取积分信息失败");
        }

        detail.setTouristInfoList(queryTouristList(localFunOrder.getId()));
        //单张票价
        BigDecimal fee = localFunOrder.getTicketsFee().divide(new BigDecimal(localFunOrder.getTicketNum()));
        //单张服务费
        BigDecimal serviceFee = localFunOrder.getServiceFee().divide(new BigDecimal(localFunOrder.getTicketNum()));
        detail.setFee(fee);
        detail.setServiceFee(serviceFee);
        return Result.success(detail);
    }


    /**
     * 获取订单状态
     * @param paymentStatus
     * @param scheduledStatus
     * @param cancelStatus
     * @return
     */
    private Integer getOrderStatus(int paymentStatus,int scheduledStatus,int cancelStatus){
        if (paymentStatus == OrderPaymentStatus.UN_PAYMENT.getCode() && scheduledStatus == 0 && cancelStatus == 0) {

            //待付款
            return AppOrderStatus.UN_PAYMENT.getCode();
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                && cancelStatus == 0) {

            //您已下單，等待確認
            return AppOrderStatus.UN_CONFIRM.getCode();
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode()
                && cancelStatus == 0) {

            //预定失败
            return AppOrderStatus.RESERVE_FAIL.getCode();
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_CANCEL.getCode()
                && scheduledStatus == 0
                && cancelStatus == 0) {

            //超时未付款,订单已取消
            return AppOrderStatus.TIME_OUT_CANCEL.getCode();
        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                && cancelStatus == 0) {
            //已完成
            return AppOrderStatus.SUCCESS.getCode();
        }  else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                && (cancelStatus == OrderCancelStatus.UNDER_APPROVAL.getCode() || cancelStatus == OrderCancelStatus.APPROVAL_FAIL.getCode())) {
            //待处理
            return AppOrderStatus.UN_HANDLE.getCode();

        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                && (cancelStatus == OrderCancelStatus.APPROVAL_SUCCESS.getCode())) {
            //待退款
            return AppOrderStatus.UN_REFUND.getCode();

        } else if (paymentStatus == OrderPaymentStatus.ALREADY_PAYMENT.getCode()
                && (scheduledStatus == OrderScheduledStatus.CONFIRM_RESERVE.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_SUCCESS.getCode()
                || scheduledStatus == OrderScheduledStatus.RESERVE_FAIL.getCode())
                && (cancelStatus == OrderCancelStatus.ALREADY_REFUND.getCode())) {

            //已退款
            return AppOrderStatus.REFUND_SUCCESS.getCode();
        }
        return null;
    }
    @Override
    public Result callPay(LocalFunOrderAppCallPayReq callPayReq) {
        log.info("【当地玩乐订单APP-唤起支付】方法入参:{}", JSON.toJSONString(callPayReq));
        Result pay = null;
        try {
            LocalFunOrder localFunOrder = localFunOrderMapper.selectOne(new QueryWrapper<LocalFunOrder>().lambda()
                    .eq(LocalFunOrder::getId, callPayReq.getId())
                    .eq(LocalFunOrder::getPaymentStatus, OrderPaymentStatus.UN_PAYMENT.getCode())
                    .eq(LocalFunOrder::getIsDeleted, IsDeletedCode.NO.getCode()));
            if (null == localFunOrder) {
                throw new BusinessException(SystemError.LOCAL_FUN_18010);
            }
            PayCommonReq payCommonReq = new PayCommonReq();
//            payCommonReq.setOrderNumber(localFunOrder.getOrderNumber());
            payCommonReq.setOrderValidTime(localFunOrder.getPayExpireDate());
            payCommonReq.setCurrency(PayCurrency.HKD);
            payCommonReq.setTotalFee(localFunOrder.getOrderAmount());
            payCommonReq.setPaymentMethod(PaymentMethod.getByCode(callPayReq.getPaymentMethodCode()));
            payCommonReq.setNotifyUrl(LocalFunOrderPay.APP_CUSTOM_URI);
            payCommonReq.setSubject("支付");
            payCommonReq.setBody("支付");
            log.info("【当地玩乐订单APP-唤起支付】支付入参:{},userId:{}", JSON.toJSONString(payCommonReq), localFunOrder.getSalesmanId());
            pay = payService.pay(payCommonReq, localFunOrder.getSalesmanId());
            log.info("【当地玩乐订单APP-唤起支付】支付回参:{}", JSON.toJSONString(pay));
        } catch (BusinessException e) {
            log.error("【当地玩乐订单APP-唤起支付】唤起支付失败失败,error:{}", e.getMessage(), e);
            throw new BusinessException(SystemError.getDefined(e.getCode()));
        } catch (Exception e) {
            log.error("【当地玩乐订单APP-唤起支付】系统异常,error:{}", e.getMessage(), e);
            throw new BusinessException(SystemError.SYS_500);
        }
        return pay;
    }

    @Override
    public Result<AppQueryPayResultDTO> queryPayResult(Long id) {
        AppQueryPayResultDTO appQueryPayResultDTO = null;
        try {
            LocalFunOrder localFunOrder = localFunOrderMapper.selectOne(Wrappers.<LocalFunOrder>lambdaQuery()
                    .eq(LocalFunOrder::getId, id)
                    .select(LocalFunOrder::getId, LocalFunOrder::getPayExpireDate,LocalFunOrder::getPaymentStatus,LocalFunOrder::getOrderAmount,LocalFunOrder::getProductId,LocalFunOrder::getUseDate,LocalFunOrder::getProductTicketsId,LocalFunOrder::getQueryNumber,
                            LocalFunOrder::getScheduledStatus, LocalFunOrder::getOrderNumber, LocalFunOrder::getQueryNumber));
            if (localFunOrder == null) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60002);
            }
            appQueryPayResultDTO = EntityUtil.copy(localFunOrder, AppQueryPayResultDTO.class);
            appQueryPayResultDTO.setInquiryNumber(localFunOrder.getQueryNumber());
            appQueryPayResultDTO.setUseDate(localFunOrder.getUseDate() != null ? localFunOrder.getUseDate().toLocalDate():null);
            appQueryPayResultDTO.setAmount(localFunOrder.getOrderAmount());
            Result<LocalFunResourceDetailDTO> result = iLocalFunResourceService.productDetail(localFunOrder.getProductId());
            if(result != null && result.getData() != null){
                appQueryPayResultDTO.setTitle(result.getData().getName());
            }

            //获取规格信息
            try {
                String productTicketsId = localFunOrder.getProductTicketsId();
                String[] split = productTicketsId.split(",");
                Long attrId1 = null;
                Long attrId2 = null;
                if(split.length > 0){
                    attrId1 = Long.valueOf(split[0]);
                }
                if(split.length == 2){
                    attrId2 = Long.valueOf(split[1]);
                }
                LocalFunStockInfo costTouristStockInfo = iLocalFunAppProductService.getCostTouristStockInfo(attrId1, attrId2);
                if(costTouristStockInfo != null){
                    appQueryPayResultDTO.setAttrName1(costTouristStockInfo.getAttrName1());
                    appQueryPayResultDTO.setAttrName2(costTouristStockInfo.getAttrName2());
                }
            } catch (NumberFormatException e) {
                log.error("获取规格信息失败");
            }


            List<LocalFunOrderCollection> airportExpressOrderCollections = localFunOrderCollectionMapper.selectList(new QueryWrapper<LocalFunOrderCollection>().lambda()
                    .eq(LocalFunOrderCollection::getOrderId, localFunOrder.getId())
                    .eq(LocalFunOrderCollection::getIsDeleted, IsDeletedCode.NO));
            if (CollectionUtils.isNotEmpty(airportExpressOrderCollections)) {
                LocalFunOrderCollection localFunOrderCollection = airportExpressOrderCollections.get(0);
                String collectionWay = localFunOrderCollection.getCollectionWay();
                appQueryPayResultDTO.setPaymentMethod(collectionWay);
                appQueryPayResultDTO.setPaymentDateTime(localFunOrderCollection.getGmtCreate());
            }
            // 构建支付结果
            if (Objects.equals(localFunOrder.getPaymentStatus(), OrderPaymentStatus.ALREADY_PAYMENT.getCode())) {
                appQueryPayResultDTO.setPaymentResult(SystemConstants.BUSINESS_SUCCESS);
                appQueryPayResultDTO.setSuccess(true);
            } else {
                appQueryPayResultDTO.setPaymentResult(SystemConstants.BUSINESS_FAIL);
                appQueryPayResultDTO.setSuccess(false);
            }
        } catch (BusinessException e) {
            log.error("【当地玩乐订单APP-查询支付结果】查询失败,error:{}", e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            log.error("【当地玩乐订单APP-查询支付结果】系统异常,error:{}", e.getMessage(), e);
            throw e;
        }
        return Result.success(appQueryPayResultDTO);
    }

    @Override
    public Result<Long> deleteCancelOrder(Long orderId) {
        LocalFunOrder localFunOrder = localFunOrderMapper.selectById(orderId);
        if(localFunOrder == null){
            throw new BusinessException(SystemError.LOCAL_FUN_18010);
        }
        //非已取消的订单不允许删除
        if(!OrderPaymentStatus.ALREADY_CANCEL.getCode().equals(localFunOrder.getPaymentStatus())){
            throw new BusinessException(SystemError.LOCAL_FUN_18030);
        }
        localFunOrder.setIsDeleted(1);
        localFunOrderMapper.updateById(localFunOrder);
        return Result.success(localFunOrder.getId());
    }

    @Override
    public CallPayDTO getCallPayInfo(Long orderId) {

        LocalFunOrder localFunOrder = localFunOrderMapper.selectOne(Wrappers.<LocalFunOrder>lambdaQuery()
                .eq(LocalFunOrder::getId, orderId)
                .eq(LocalFunOrder::getPaymentStatus, OrderPaymentStatus.UN_PAYMENT.getCode())
                .eq(LocalFunOrder::getIsDeleted, IsDeletedCode.NO.getCode())
                .select(LocalFunOrder::getId, LocalFunOrder::getOrderNumber, LocalFunOrder::getOrderAmount,LocalFunOrder::getSource,
                        LocalFunOrder::getPayExpireDate, LocalFunOrder::getSalesmanId, LocalFunOrder::getPaymentStatus));
        if (localFunOrder == null) {
            throw new BusinessException(SystemError.LOCAL_FUN_18010);
        }
        CallPayDTO callPayDTO = EntityUtil.copy(localFunOrder, CallPayDTO.class);
        callPayDTO.setOrderValidTime(localFunOrder.getPayExpireDate());
        callPayDTO.setTotalFee(localFunOrder.getOrderAmount());
        callPayDTO.setCurrency(com.ctshk.common.enums.payment.PayCurrency.HKD);
        callPayDTO.setSubject("当地玩乐订单支付");
        callPayDTO.setBody("当地玩乐订单支付");
        return callPayDTO;
    }

    /**
     * 旅客信息
     * @param orderId
     * @return
     */
    private List<LocalFunTouristInfo> queryTouristList(Long orderId) {
        List<LocalFunOrderTourist> localFunOrderTourists = localFunOrderTouristMapper.selectList(Wrappers.<LocalFunOrderTourist>lambdaQuery().
                eq(LocalFunOrderTourist::getOrderId, orderId));
        return EntityUtil.copyList(localFunOrderTourists,LocalFunTouristInfo.class);
    }

    /**
     * 根据币种名称获取汇率
     *
     * @param currencySy
     * @return
     */
    private BigDecimal getCrmExchangeRateByName(String currencySy) {
        List<MainDataCurrencyQueryDTO> list = iMainDataCurrencyService.queryList(Lists.newArrayList(Long.valueOf(currencySy)));

        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException(SystemError.AIREXPRESS_ORDER_60003);
        }
        MainDataCurrencyQueryDTO currencyQueryDTO = list.stream().findFirst().orElse(null);
        if (currencyQueryDTO == null) {
            throw new BusinessException(SystemError.AIREXPRESS_ORDER_60003);
        }
        return currencyQueryDTO.getCrmExchangeRate();
    }

    /**
     * 保存订单信息
     * @param orderPorductReq 入参订单信息
     * @param user            用户ID
     * @param orderId         订单ID
     * @param isPackage       是否单品销售
     * @param userId
     * @param orderSource
     * @param loginUserId
     */
    private LocalFunOrder saveOrderInfo(LocalFunH5OrderPorductReq orderPorductReq, UserDTO user, long orderId, int isPackage, Long userId, Integer orderSource, Long loginUserId) {
        //获取产品信息
        Result<LocalFunPriceDTO> result2 = iLocalFunAppProductService.getPrice(LocalFunPriceReq.builder().productId(orderPorductReq.getProductId())
                .attrId1(orderPorductReq.getAttr1Id()).attrId2(orderPorductReq.getAttr2Id()).channelId(orderPorductReq.getChannelId())
                .source(OrderSource.PC_NET.getCode()).queryDate(LocalDate.now()).build());

        LocalFunPriceDTO localFunPriceDTO = result2.getData();
        if(localFunPriceDTO == null ){
            throw new BusinessException(SystemError.LOCAL_FUN_18022);
        }

        log.info("当地玩乐---->获取产品价格：{}",JSON.toJSONString(localFunPriceDTO));

        LocalFunOrder localFunOrder = EntityUtil.copy(orderPorductReq, LocalFunOrder.class);
        localFunOrder.setContactName(localFunOrder.getSurname()+localFunOrder.getName());
        // 服务费用
        //预定服务费
        BigDecimal serviceFee = new BigDecimal(Math.ceil(localFunPriceDTO.getServiceFee().doubleValue()));
        // 1.设置服务费(单服务费*门票数)
        localFunOrder.setServiceFee(serviceFee.multiply(new BigDecimal(orderPorductReq.getNum())));
        BigDecimal singleTicketFee = new BigDecimal(Math.ceil(localFunPriceDTO.getCostPrice().multiply(localFunPriceDTO.getExchangeRate()).add(localFunPriceDTO.getAddFee()).doubleValue()));
        // 2.设置门票总额(单张门票价格*门票数)
        localFunOrder.setTicketsFee(getTicketsFee(singleTicketFee, orderPorductReq.getNum()));
        // 应收总额
        localFunOrder.setOrderAmount(new BigDecimal(Math.ceil(localFunOrder.getServiceFee().add(localFunOrder.getTicketsFee()).doubleValue())));
        // 4.设置订单信息
        localFunOrder.setUseDate(DateUtil.toLocalDateTime(orderPorductReq.getUseDate()));
        localFunOrder.setTicketNum(orderPorductReq.getNum());
        LocalDateTime createTime = LocalDateTime.now();
        localFunOrder.setId(orderId);
        localFunOrder.setProductTicketsId(orderPorductReq.getAttr1Id()+","+orderPorductReq.getAttr2Id());
        //待付款
        localFunOrder.setPaymentStatus(OrderPaymentStatus.UN_PAYMENT.getCode());
        // 1:中旅H5,2:APP-Android,3:APP-中旅iOS,4:PC-中旅網"
        localFunOrder.setSource(orderSource);
        // 销售方式(1：单品销售 2：打包销售)
        localFunOrder.setSalesMethods(isPackage);
        localFunOrder.setProductType(1);//产品类型(1手工单，2外挂单)
        /**最晚付款时间为创建订单后15分钟*/
        localFunOrder.setPayExpireDate(createTime.plusMinutes(30));
        localFunOrder.setGmtCreate(createTime);
        localFunOrder.setGmtModified(createTime);
        localFunOrder.setUserId(loginUserId);

        String inquiryNumber = generatorInquiryNumber();
        localFunOrder.setQueryNumber(inquiryNumber);
        //是否游客身份
        Boolean loginUser = userId != null;
        if(loginUser){
            localFunOrder.setCreateId(userId);
            localFunOrder.setSalesmanId(user.getId());
            localFunOrder.setSalesmanName(user.getUsername());
            SysDepartmentDTO sysDepartmentDTO = iSysDepartmentService.queryByUserId(userId);
            localFunOrder.setOrderNumber(loginUser? LocalFunOrderGenerator.getOrderNumer(sysDepartmentDTO.getDeptCode(),user.getEmployeeNumber()) :LocalFunOrderGenerator.getVisitorOrderNumer());
        }else {
            localFunOrder.setOrderNumber(LocalFunOrderGenerator.getVisitorOrderNumer());
        }

        //设置产品信息
        Result<LocalFunResourceDetailDTO> result = iLocalFunResourceService.productDetail(orderPorductReq.getProductId());
        if (result.getData() != null) {
            LocalFunResourceDetailDTO detail = result.getData();
            localFunOrder.setProductCityId(detail.getCityId());
            localFunOrder.setProductCityName(detail.getCityName());
            localFunOrder.setProductFunType(detail.getFunType());
            localFunOrder.setProductFunName(detail.getFunName());
            localFunOrder.setProductName(detail.getName());
        }
        // 3.设置订单总额 = 应收总额 - 积分折扣 - 优惠折扣
        localFunOrder.setReceivableAmount(getOrderAmount(localFunOrder, orderPorductReq,loginUser));
        localFunOrderMapper.insert(localFunOrder);

        try {
            // 下单完成后调用任务执行如果未付款则超时失效订单操作
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", orderId);
            // 延迟时间,单位毫秒,1800000L=30分钟后执行
            long delayMS = 1800000L;
            OhMyClient taskClient = new OhMyClient(domain, appName, password);
            ResultDTO<Long> resultTask = taskClient.runJob(jobId, jsonObject.toJSONString(), delayMS);

            if (resultTask.isSuccess()) {
                // 任务执行成功,过期时间*2是防止任务启动时redis数据已过期
                redisTemplate.opsForValue().set(RedisConstants.ORDER_INSTANCELD_KEY + orderId, resultTask.getData(), delayMS * 2, TimeUnit.MILLISECONDS);
            }
        } catch (Exception e) {
            log.error("当地玩乐订单-订单超时API任务异常：{}", e.getMessage());

            // 延迟定时任务，15分钟后会自动取消订单，仅执行一次
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
            try {
                executor.schedule(new OrderCancelScheduleTask(localFunOrder.getId(), localFunOrderMapper), 15, TimeUnit.MINUTES);
            } finally {
                executor.shutdown();
            }
        }
        return localFunOrder;
    }
    /**
     * 生成查询号码，六位随机数字字符串
     *
     * @return
     */
    public static String generatorInquiryNumber() {
        String randomNumber = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
        return randomNumber;
    }
    /**
     * 设置订单总额
     *
     * @param localFunOrder
     * @param loginUser
     * @return
     */
    private BigDecimal getOrderAmount(LocalFunOrder localFunOrder, LocalFunH5OrderPorductReq localFunAppOrderPorductReq, Boolean loginUser) {
        // 积分费用
        BigDecimal integralFee = localFunOrder.getIntegralDeduction();
        // 推广码优惠券费用
        BigDecimal couponDeduction = localFunOrder.getCouponDeduction();
        // 应收总额
        BigDecimal receivableAmount = localFunOrder.getOrderAmount();
        // 会员登录, 积分系统扣减积分
        if (loginUser && !Objects.isNull(localFunOrder.getIntegral()) && localFunOrder.getIntegral() != 0) {
            try {
                TransactionIntegralReq transactionIntegralReq = new TransactionIntegralReq();
                transactionIntegralReq.setCtsLogin(localFunAppOrderPorductReq.getCtsLogin());
                transactionIntegralReq.setCtsPassword(localFunAppOrderPorductReq.getCtsPassword());
                transactionIntegralReq.setOrderNumber(localFunOrder.getOrderNumber());
                transactionIntegralReq.setPoints(new BigDecimal(localFunOrder.getIntegral()));
                Result result = iStarVipBusinessService.transactionIntegral(transactionIntegralReq);
                if (result.getCode() != 1) {
                    throw new BusinessException(SystemError.LOCAL_FUN_18011);
                }
            } catch (BusinessException e) {
                throw new BusinessException(SystemError.LOCAL_FUN_18011);
            }
        }
        // 最终订单总额=应收总额-积分扣减-优惠券扣减
        integralFee = Objects.isNull(integralFee) ? BigDecimal.ZERO : integralFee;
        couponDeduction = Objects.isNull(couponDeduction) ? BigDecimal.ZERO : couponDeduction;
        return receivableAmount.subtract(integralFee).subtract(couponDeduction);
    }

    /**
     * 设置门票总额(单张门票价格*门票数)
     *
     * @param singleTicketFee
     * @param num
     * @return
     */
    private BigDecimal getTicketsFee(BigDecimal singleTicketFee, Integer num) {
        return singleTicketFee.multiply(BigDecimal.valueOf(num));
    }

    /**
     * 登记旅客资料
     * @param userId       用户ID
     * @param orderId      订单ID
     * @param req
     */
    private void registerTouristInfo(Long userId, long orderId,LocalFunH5OrderReq req) {
        LocalFunH5OrderPorductReq localFunAppOrderPorductReq = req.getLocalFunAppOrderPorductReq();
        if (CollectionUtils.isNotEmpty(req.getTouristInfos())) {
            LocalFunOrderTourist localFunOrderTourist;
            for (LocalFunH5OrderTourisReq touristInfo : req.getTouristInfos()) {
                localFunOrderTourist = EntityUtil.copy(touristInfo, LocalFunOrderTourist.class);
                localFunOrderTourist.setId(SnowflakeIdWorker.nextId());
                localFunOrderTourist.setOrderId(orderId);
                localFunOrderTourist.setCreateId(userId);
                localFunOrderTourist.setTouristName(localFunOrderTourist.getSurname()+localFunOrderTourist.getName());

                try {
                    Long channelId = req.getOrderSource() == 3?ChannelMainData.CHINA_TRAVEL.getId():ChannelMainData.APP_H5.getId();
                    LocalFunPriceRemainderDTO localFunSalePriceInfoHandle = iLocalFunProductService.findLocalFunSalePriceInfoHandle(3, localFunAppOrderPorductReq.getProductId(), LocalDateTime.now().toLocalDate(), channelId, localFunAppOrderPorductReq.getAttr1Id(), localFunAppOrderPorductReq.getAttr2Id());
                    localFunOrderTourist.setSinglePrice(new BigDecimal(Math.ceil(localFunSalePriceInfoHandle.getPrice().doubleValue())));
                    localFunOrderTourist.setCharge(Objects.isNull(localFunSalePriceInfoHandle.getReserveCharge())?null:new BigDecimal(Math.ceil(localFunSalePriceInfoHandle.getReserveCharge().doubleValue())));
                } catch (Exception e) {
                    log.error("记录旅客票价信息失败：{}",e.getMessage());
                }
                localFunOrderTouristMapper.insert(localFunOrderTourist);
            }
        }
    }



    /**
     * 生成供应预订单
     * @param currentUser
     * @param localFunOrder
     * @param result
     */
    private void callSupplierOrder(UserDTO currentUser, LocalFunOrder localFunOrder, Result<LocalFunResourceDetailDTO> result) {
        // 生成供应预订单
        SupplierOrderSystemLocalFunAddReq supplierOrderSystemAirExpressAddReq = new SupplierOrderSystemLocalFunAddReq();
        supplierOrderSystemAirExpressAddReq.setOrderType(1);
        supplierOrderSystemAirExpressAddReq.setSupplierOrderType("1");
        supplierOrderSystemAirExpressAddReq.setBusinessType(SystemBusinessType.LOCAL_FUN.getCode());
        supplierOrderSystemAirExpressAddReq.setTotalFee(localFunOrder.getOrderAmount());
        supplierOrderSystemAirExpressAddReq.setPayableAmount(localFunOrder.getReceivableAmount());
        supplierOrderSystemAirExpressAddReq.setSaleNumber(localFunOrder.getOrderNumber());
        supplierOrderSystemAirExpressAddReq.setConfirmStatus(localFunOrder.getScheduledStatus());
        supplierOrderSystemAirExpressAddReq.setReserveTypeId(SupplierReserveTypeEnum.LOCAL_FUN.getId());

        MainDataCurrencyQueryDTO currencyEntity = iMainDataCurrencyService.getExchangeCurrencyEntity("HKD", CurrencyRateExchangeConstant.MARKET_EXCHANGE_RATE_);
        supplierOrderSystemAirExpressAddReq.setCurrencyId(currencyEntity.getId());
        supplierOrderSystemAirExpressAddReq.setCurrency("HKD");
        supplierOrderSystemAirExpressAddReq.setSupplierType(1L);
        supplierOrderSystemAirExpressAddReq.setSaleType(SalesMethod.SINGLE_SALE.getCode());
        supplierOrderSystemAirExpressAddReq.setReserveStatus(localFunOrder.getScheduledStatus());
        supplierOrderSystemAirExpressAddReq.setSupplierOrderNumber(localFunOrder.getOrderNumber());

        if(result.getData() != null){
            LocalFunResourceDetailDTO detailDTO = result.getData();
            supplierOrderSystemAirExpressAddReq.setProductNumber(detailDTO.getProductCode());
            supplierOrderSystemAirExpressAddReq.setProductName(detailDTO.getName());
            supplierOrderSystemAirExpressAddReq.setSupplierId(detailDTO.getSupplierId());
            supplierOrderSystemAirExpressAddReq.setSupplierName(detailDTO.getSupplierName());
            supplierOrderSystemAirExpressAddReq.setProductType(detailDTO.getSourceType());

            UserDTO userDTO = iSysUserService.loadUserByParam(detailDTO.getChargeUserId(), 1);
            supplierOrderSystemAirExpressAddReq.setDepartmentId(userDTO.getDeptId());
            supplierOrderSystemAirExpressAddReq.setDepartment(userDTO.getDept());

            //二次确认
            if (result.getData().getBookConfirm() == 2) {
                supplierOrderSystemAirExpressAddReq.setReserveStatus(OrderScheduledStatus.CONFIRM_RESERVE.getCode());
                supplierOrderSystemAirExpressAddReq.setConfirmStatus(SupplierConfirmStatus.UN_CONFIRM.getCode());
            } else {  //立即确认
                supplierOrderSystemAirExpressAddReq.setReserveStatus(OrderScheduledStatus.RESERVE_SUCCESS.getCode());
                supplierOrderSystemAirExpressAddReq.setConfirmStatus(SupplierConfirmStatus.CONFIRMED.getCode());
            }
        }
        supplierOrderSystemAirExpressAddReq.setSupplierSystemOrderLocalFunAddReqList(createLocalFunData(result,localFunOrder));
        iSupplierOrderService.addSystemLocalFun(supplierOrderSystemAirExpressAddReq, currentUser.getId());
    }



    /**
     *
     *
     * @param result
     * @param localFunOrder
     * @return
     */
    private List<SupplierSystemOrderLocalFunAddReq> createLocalFunData(Result<LocalFunResourceDetailDTO> result, LocalFunOrder localFunOrder) {
        List<SupplierSystemOrderLocalFunAddReq> list = Lists.newArrayListWithExpectedSize(10);

        //當地玩樂僅單個產品 添加一個即可 <系统内当地玩乐基础信息>
        SupplierSystemOrderLocalFunAddReq req = new SupplierSystemOrderLocalFunAddReq();
        req.setOrderId(localFunOrder.getId());
        req.setCustomerRemark(localFunOrder.getRemark());
        req.setSupplierRemark(null);
        if(result.getData() != null){
            req.setSuitablePeople(result.getData().getChargeUser());
        }

        QueryWrapper<LocalFunOrderTourist> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LocalFunOrderTourist::getOrderId,localFunOrder.getId());
        List<LocalFunOrderTourist> localFunOrderTourists = localFunOrderTouristMapper.selectList(queryWrapper);

        //本地玩乐详情列表
        if(CollectionUtils.isNotEmpty(localFunOrderTourists)){
            List<SupplierSystemOrderLocalFunDetailAddReq> addReqs = localFunOrderTourists.stream().map(entity -> {
                SupplierSystemOrderLocalFunDetailAddReq addReq = new SupplierSystemOrderLocalFunDetailAddReq();
                addReq.setAirExpressInfoId(null);
                addReq.setNumber(localFunOrder.getTicketNum());
                addReq.setOrderId(localFunOrder.getId());
                addReq.setPassengerName(entity.getTouristName());

                //門票單價
                if(localFunOrder.getTicketsFee() != null && localFunOrder.getTicketNum() != null){
                    addReq.setPrice(localFunOrder.getTicketsFee().divide(new BigDecimal(localFunOrder.getTicketNum())));
                }
                if (result.getData() != null) {
                    addReq.setProductName(result.getData().getName());
                    addReq.setProductNumber(result.getData().getProductCode());
                }
                return addReq;
            }).collect(Collectors.toList());

            req.setSupplierSystemOrderLocalFunDetailAddReqList(addReqs);
        }
        list.add(req);
        return list;
    }


    /**
     * 收款
     * @param payOrderReq
     * @param id
     */
    protected LocalFunOrderCollection addPcCollection(NotifyConsumeReq payOrderReq, Long id) {
        String collectionNumber = LocalFunOrderGenerator.getCollectionNumber();
        LocalFunOrderCollection localFunOrderCollection = new LocalFunOrderCollection();
        localFunOrderCollection.setCollectionAmount(payOrderReq.getAmount());
        localFunOrderCollection.setCollectionNumber(collectionNumber);
        localFunOrderCollection.setOrderId(id);
        localFunOrderCollection.setIsPos(0);
        localFunOrderCollection.setIsUnionpayDiscount(0);
        localFunOrderCollection.setCurrencyId(1365184144700788737L);
        localFunOrderCollection.setPayer(payOrderReq.getPaymentAccount());
        localFunOrderCollection.setCurrency(payOrderReq.getCurrency());
        localFunOrderCollection.setStatus(OrderCollectionStatus.UN_REJECT.getCode());
        localFunOrderCollection.setCollectionWay(PaymentMethod.getByCode(payOrderReq.getPaymentMethod()).getName());
        localFunOrderCollection.setCollectionWayId(PaymentMethod.getByCode(payOrderReq.getPaymentMethod()).getPayRefundMethodId());
        localFunOrderCollectionMapper.insert(localFunOrderCollection);
        return localFunOrderCollection;
    }

    /**
     * 收据
     * @param id
     * @param localFunOrder
     */
    private void addOrderReceipt(UserDTO userDTO, Long id, LocalFunOrder localFunOrder) {
        LocalFunOrderReceipt scenicOrderReceipt = new LocalFunOrderReceipt();
        scenicOrderReceipt.setOrderId(id);
        //門市編號+員工編號+年後2位+月日4位+A+時分秒6位+（S）
        Calendar cal = Calendar.getInstance();
        int hour=cal.get(Calendar.HOUR);//小时
        int minute=cal.get(Calendar.MINUTE);//分
        int second=cal.get(Calendar.SECOND);//秒
        String hourNew = String.valueOf(hour);
        String minuteNew = String.valueOf(minute);
        String secondNew = String.valueOf(second);
        if(hourNew.length() <2 ){
            hourNew = "0" + hourNew;
        }
        if(minuteNew.length() <2 ){
            minuteNew = "0" + minuteNew;
        }
        if(secondNew.length() <2 ){
            secondNew = "0" + secondNew;
        }
        String time =  hourNew + minuteNew + secondNew;
        String receiptNo = userDTO.getDept() + userDTO.getEmployeeNumber() + DateUtil.fmtNum(LocalDate.now()) + "A" + time + "(s)";
        scenicOrderReceipt.setReceiptNo(receiptNo);
        scenicOrderReceipt.setBranch(userDTO.getEmployeeNumber() + "-" + userDTO.getDept());

        Long receiptId = SnowflakeIdWorker.nextId();
        scenicOrderReceipt.setId(receiptId);
        scenicOrderReceipt.setCreateId(userDTO.getId());
        scenicOrderReceipt.setGmtCreate(LocalDateTime.now());
        scenicOrderReceipt.setGuest(localFunOrder.getContactName());
        scenicOrderReceipt.setPhone(localFunOrder.getContactMobile());
        scenicOrderReceiptMapper.insert(scenicOrderReceipt);
    }

    /**
     * 构建订单ESDTO
     * @param orderId
     * @return
     */
    public MyLocalFunOrderDTO buildEsOrderDTO(Long orderId) {
        LocalFunOrder localFunOrder = baseMapper.selectById(orderId);
        MyLocalFunOrderDTO orderDTO = EntityUtil.copy(localFunOrder, MyLocalFunOrderDTO.class);

        LocalFunProductDetailReq req = new LocalFunProductDetailReq();
        req.setId(orderDTO.getProductId());
        Result<LocalFunProductDetailByIdDTO> localFunProductDetailByIdDTOResult = iLocalFunProductService.localFunProductDetailByIdDTO(req);
        if(localFunProductDetailByIdDTOResult.isSuccess()) {
            LocalFunProductDetailByIdDTO data = localFunProductDetailByIdDTOResult.getData();
            if(data.getVaildType() == 1) {
                Double vaildDay = data.getVaildDay();
                LocalDateTime gmtCreate = orderDTO.getGmtCreate();
                orderDTO.setVaildDayBegin(gmtCreate);
                orderDTO.setVaildDayEnd(gmtCreate.plusDays(vaildDay.longValue()));
            } else if(data.getVaildType() == 2){
                orderDTO.setVaildDayBegin(data.getVaildDayBegin());
                orderDTO.setVaildDayEnd(data.getVaildDayEnd());
            }
        }

        return orderDTO;
    }

    /**
     * 异步发送订单数据到个人中心
     * @param orderId 订单Id
     */
    public void sendOrderToAppUser(Long orderId) {
        CompletableFuture.runAsync(() -> {
            try {
                MyLocalFunOrderDTO orderDTO = buildEsOrderDTO(orderId);
                orderEsService.saveOrderToEs(orderDTO, SystemBusinessType.LOCAL_FUN);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 异步更新订单状态到个人中心
     */
    public void updateStatusToAppUser(Long orderId) {
        CompletableFuture.runAsync(() -> {
            try {
                LocalFunOrder order = baseMapper.selectById(orderId);
                orderEsService.updateStatusToEs(order.getId(),SystemBusinessType.LOCAL_FUN.getCode(),
                        null, order.getPaymentStatus(), order.getScheduledStatus(),
                        order.getCancelStatus());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
}
